🤖 feat: choose what a settings backup carries - #3985
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbfabe752e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This comment has been minimized.
This comment has been minimized.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7c2d5ad4be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: 7c2d5ad4be
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 543d699c8f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 543d699c8f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This comment has been minimized.
This comment has been minimized.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 875b0c8c82
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This comment has been minimized.
This comment has been minimized.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9f9f51be0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: b9f9f51be0
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9fd948f88e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: 9fd948f88e
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
|
@codex review |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38cdefbd50
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
This comment has been minimized.
This comment has been minimized.
|
@codex review |
This comment has been minimized.
This comment has been minimized.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39b3c721eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f68116c450
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Security Review
Here are some automated security review suggestions for this pull request.
Reviewed commit: f68116c450
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
|
@codex review |
This comment has been minimized.
This comment has been minimized.
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Replace credential detection in the MCP export with a per-category content
selection saved in settingsBackup (includeInstructions, includeAgents,
includeSkills, includeGlobalMemory, includeMcp, includeMcpHeaders,
includeMcpCommands, includePreferences; includeProjects keeps its opt-in
default). One selection governs both directions: collection and export skip
unselected categories, and a restore only writes selected ones.
MCP header values and stdio commands are published as written when selected,
gated by the existing byte-bound secret-scan approval. When deselected they
become the existing redaction marker, so a restore keeps this machine's values;
the same projection is applied to a checked-out backup at restore time so the
restoring machine's selection wins. Literal headers from a backup now restore
verbatim; {secret: NAME} references keep the local-only endpoint-match rule.
The Backup settings screen replaces the static "Included" list with the
checkbox selection (MCP has two indented sub-options).
e6352db to
af1bc9f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: af1bc9f976
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Review follow-ups: readBackupPayload skips unselected manifest entries so a deselected category is never parsed; the preview says when MCP is excluded; every content toggle has a Ctrl+Alt shortcut.
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
The informational-summary allow-list rejected a completed board that lists security findings Codex itself marks Resolved, so the Codex Comments job failed on a PR with no open finding. Accept only that exact shape (resolved, linking to a thread on this PR); live advisories and unknown headings still block.
|
@codex review New head 2312afa adds one CI-only commit: the Codex Comments gate now accepts a completed status board whose findings are all marked Resolved (this PR's board lists 43 resolved advisories from the earlier revision, which made the job fail with zero open findings). Product code is unchanged from 5bca829. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2312afad94
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
With a category deselected, the restore-side projection now marks the field even when the backup entry does not carry it, so the existing rehydration keeps this machine's value instead of dropping it with the entry. Exports are unchanged.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 354ed9213e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
… markers parseManifest drops mcpRedactions unread when the selection leaves MCP alone, so a malformed or oversized list cannot fail a restore of the other categories. The restore-side projection no longer applies the publish caps to the markers it adds for absent deselected fields, so a large valid backup stays restorable when a category is deselected.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef0346acfe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A backup written when header values were redacted one by one lists child paths; deselecting headers now replaces the object with one marker, and the stale child path made the restore reject the manifest. Keep only listed paths that still name a marker in the projected file.
parseManifest now filters entries by the content selection before the per-entry checks, so a malformed entry for a category the restore leaves alone cannot fail it. This replaces the read-loop skip.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f1f575a55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function parseManifest(raw: string, portable: boolean, contents?: BackupContents): BackupManifest { | ||
| const tree = jsonc.parseTree(raw); | ||
| if (!tree) throw new Error("Invalid backup manifest"); | ||
| assertNoDuplicateKeys(tree, "backup manifest"); |
There was a problem hiding this comment.
Filter deselected entries before checking duplicate keys
When restoring with a category deselected—for example, includeSkills: false—a corrupt manifest entry for that category containing duplicate sha256 keys still aborts preview and restore. Fresh evidence beyond the resolved invalid-digest case is that assertNoDuplicateKeys recursively walks the entire manifest here before the selection filter at line 1801 runs, even though the deselected file is never read or written. Filter the manifest tree first or restrict duplicate-key validation to retained entries.
AGENTS.md reference: AGENTS.md:L111-L111
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Not changing this one, and leaving the thread open for a human decision rather than resolving it.
Duplicate-key validation is a document-level check that has to run before the selection filter, not after it: the filter classifies each entry by its path key, and an entry with duplicate keys has no single trustworthy path (the JSONC tree carries both values while JSON.parse keeps the last). Filtering first would let a crafted entry present an unselected path to the tree walk and a selected one to the parsed object, so the whole manifest is rejected as malformed before any of it is trusted. The earlier fixes in this series (entries, mcpRedactions, per-file parsing) skip category-specific content whose classification is unambiguous; a manifest that is not a well-formed document is a different thing, and refusing to restore from it is the intended behavior.
Summary
The settings backup now lets the user choose what it carries. Nine checkboxes in the Backup settings form select the categories (global instructions, agent definitions, skills, global memory, portable preferences, MCP server configuration, and under MCP the HTTP header values and stdio commands) alongside the existing project opt-in. The same selection governs export and restore: an unselected category is absent from the published backup and is never written by a restore. Deselected MCP headers or commands become the existing redaction marker, so a restore keeps this machine's values for them.
Background
Backups publish
mcp.jsonc, and MCP header values, stdio commands, and URLs commonly hold credentials. The earlier revision of this PR tried to solve that with credential-format detection and shell-grammar redaction ofNAME=valueassignments. That approach guesses at what is secret, fails closed on shapes it cannot parse, and makes the user rehydrate redacted values on every restore even when they wanted them published. Per review discussion, this PR replaces detection with an explicit choice: the user decides which categories a backup carries, and anything sensitive that is still selected goes through the existing byte-bound secret-scan approval.Supersedes the redaction approach previously on this PR (old head
e6352db362).Implementation
settingsBackup.tsadds optionalinclude*flags next toincludeProjects;resolveBackupContents()applies defaults once (all on, projects off as before, which was a deliberate privacy default in 🤖 feat: opt-in project bundle for settings backup #4043). Olderconfig.jsonfiles load unchanged.Export:
collectAllowlistedFilesandscanBackupFilesForSecretstake the resolved contents, so unselected categories are never read or scanned.redactMcpConfignow receives anMcpProjectionOptions(headers and commands on or off) instead of deciding by pattern; deselected fields become__MUX_BACKUP_REDACTED__and are listed inmcpRedactions.Approval gate:
mcpConfigRequiresPublishApprovalflags selected stdio commands, credential-bearing URLs, and now literal header values too. A{secret: NAME}reference names a secret without carrying it, so it does not trigger approval. URL credentials are covered by the approval gate only; no detection.Restore:
readBackupPayloadtakes the current machine's selection and skips unselected manifest entries before opening them, so a deselected category is never read or parsed and a malformed file there cannot block a restore of the rest. The selected payload is then projected throughselectBackupContentsbefore preview, approval, and restore, so a machine with headers unchecked keeps its own header values whether the backup carries them or omits the field entirely, and unselected local files are no longer reported as local-only.Literal headers from a backup restore verbatim on a fresh machine (a repository editor could already read them).
{secret: NAME}references keep the local-only plus endpoint-match rule, since redirecting a secret reference to a different URL would exfiltrate a value the repository never held.UI: the static "Included" card is replaced by the checkbox list inside the settings form. MCP sub-options are indented and disabled when MCP is unchecked, and their shortcuts are inert while the parent is off. Every toggle has a
Ctrl+Altshortcut (listed under Keybinds, hint hidden on mobile widths). The preview's "Kept on this device" card says so when MCP is excluded from the backup entirely.CI: the Codex Comments gate's informational-summary allow-list now accepts a completed status board whose security findings Codex itself marks Resolved (linking to a thread on this PR). This PR's board carries 43 such lines from the earlier revision, so the job failed with zero open findings. Live advisories and unknown headings still block; four fixture rows cover both directions.
Validation
Risks
mcp.jsoncafterreadBackupPayloadhas verified the manifest hashes, so the on-disk checkout is never modified; the manifest file list is filtered in step with the files, and the integration test pins the round trip.Generated with
xum• Model:anthropic:claude-fable-5-1• Thinking:xhigh• Cost:$1137.63